package com.hystrix.command;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.hystrix.collapser.PersonClient;
import com.hystrix.entity.Person;
import com.netflix.hystrix.HystrixCollapser;
import com.netflix.hystrix.HystrixCommand;
import com.netflix.hystrix.HystrixCommandGroupKey;
import feign.Feign;
import feign.gson.GsonDecoder;
import feign.gson.GsonEncoder;
import org.apache.commons.lang.StringEscapeUtils;

import java.util.*;

/**
 * 合并执行命令
 */
public class CollapsedCommand extends HystrixCommand<Map<String,Person>> {

    //请求集合，第一个类型是单个请求返回的数据类型，第二是请求参数的类型
    Collection<HystrixCollapser.CollapsedRequest<Person,String>> requests;

    public CollapsedCommand( Collection<HystrixCollapser.CollapsedRequest<Person,String>> requests) {
        //调用父类的构造器，设置命令组的key，默认用来作为线程池的key
        super(Setter.withGroupKey(HystrixCommandGroupKey.Factory
                .asKey("ExampleGroup")));
        this.requests = requests;
    }

    @Override
    protected Map<String,Person> run() throws Exception {
        System.out.println("收集参数后执行命令，参数数量：" + requests.size());
        //处理参数
        List<String> personNames = new ArrayList<>();
        requests.forEach(request->personNames.add(request.getArgument()));
        //调用服务
        PersonClient personClient = Feign.builder().
                encoder(new GsonEncoder()).
                target(PersonClient.class, "http://localhost:8080/");
        String result = StringEscapeUtils.unescapeHtml( personClient.personList(personNames.toArray(new String[personNames.size()])) );
        Map<String ,Person> personMap = JSONObject.parseObject(result ,new TypeReference<HashMap<String,Person>>() {});
        return personMap;
    }

    //模拟服务返回
    private Map<String,Person> callService(List<String> personNames) {
        Map<String, Person> result = new HashMap<>();
        personNames.forEach(psersonName->{
            Random r = new Random();
            Person p = new Person();
            p.setId(r .nextLong());
            p.setName(psersonName);
            result.put(psersonName, p);
        });
        return result;
    }

    @Override
    protected Map<String,Person> getFallback() {
        System.out.println("CollapsedCommand 执行 fallback "   );
        return  null;
    }
}
